// Test1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "cfixedframerate.h"
#include "ccube.h"
#include <soil.h>
#pragma comment(lib,"SOIL.lib")

//u-int SOIL_load_OGL_texture( const char *?lename, int force_channels, u-int reuse_texture_ID, u-int ?ags )

#define MOVE_STEP .4
#define ANGLE_STEP 0.2
#define PI 3.1416f

bool g_bKey_o = false;
bool g_bKey_d = false;
bool g_bKey_s = false;
bool g_bKey_c = false;

float g_x=0.0f;
float g_y=0.0f;
float g_z=10.0f;
float g_roll= 0.0f;
float g_pitch= 0.0f;
float g_yaw= 0.0f;
float g_bx=0.0f;

int g_w;
int g_h;
bool solid;
bool culling=false;
bool ese=false;

float g_cubeAngle= 0.f;
CCube g_ccube1;
CCube g_ccube2;

void Keyboard(unsigned char key,int x, int y)
{
	//keyboard callback function	
	switch (key)
	{
		case 'c':	culling = !(culling);
					if(culling)
					{
						glEnable(GL_CULL_FACE);
					}
					else
					{
						glDisable(GL_CULL_FACE);
					}
					break;
		case 'm':	solid = !(solid); break;
		case 's':	ese = !(ese);
					if(ese)
					{
						glEnable(GL_DEPTH_TEST);
					}
					else
					{
						glDisable(GL_DEPTH_TEST);
					}
					break; 
		case '8':	g_bKey_o=true; break;
		case '2':	g_bKey_d=true; break;
		case '6':	g_bKey_s=true; break;
		case '4':	g_bKey_c=true; break;
		case 27: exit(0);
	}
}


void Mouse(int x, int y)
{	
		g_yaw+=(x-g_bx)*0.5;
		g_bx=x;		
}

void KeyboardUp(unsigned char key,int x, int y)
{
	switch (key)
	{		
		case '8':	g_bKey_o=false; break;
		case '2':	g_bKey_d=false; break;
		case '6':	g_bKey_s=false; break;
		case '4':	g_bKey_c=false; break;
		case 27: exit(0);
	}	
}

void Set3DView()
{	
	GLfloat spotdir[] = {-1.0,-1.0,-1.0};
	GLfloat position[] = {2.0,2.0,2.0};

	//set projection matrix
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();

	glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,(GLfloat *)spotdir);
	glLightfv(GL_LIGHT0, GL_POSITION, (GLfloat *)position);

	glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);

	//set modelview matrix
	glMatrixMode (GL_MODELVIEW);
	glLoadIdentity ();
	glRotatef(-g_roll, 0.0, 0.0, 1.0);	
	glRotatef(-g_yaw, 0.0, 1.0, 0.0);
	glRotatef(-g_pitch, 1.0, 0.0, 0.0);	
	glTranslatef(-g_x, -g_y, -g_z);
}


/*
void DrawCube()
{
	glColor3f (0.5, 1.0, 0.5);
	glMatrixMode(GL_MODELVIEW);
	
	glRotatef(g_cubeAngle,1.0,0.0,0.0);
	glutWireCube (1.0);
}
*/

void DrawScene(void)
{
	//clean the backbuffer
	glClear (GL_COLOR_BUFFER_BIT);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//viewing transformation
	Set3DView();

	//dibuja el cubo 
	
	glPushMatrix();	
		g_ccube1.setColor(0,255,0);
		g_ccube1.setPosition(0.0,0.5,0.0);
		g_ccube1.setScale(0.5,0.5,0.5);	
		g_ccube1.draw(solid);
	glPopMatrix();

	glPushMatrix();
		g_ccube2.setColor(255,0,0);
		g_ccube2.setPosition(0.0,0.0,-3.0);
		g_ccube2.setScale(2,2,2);
		g_ccube2.draw(solid);
	glPopMatrix();

}

void Reshape (int w, int h)
{
	//Reshape callback function
	g_h= h;
	g_w= w;
	glViewport (0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
	glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
}

int main(int argc, char** argv)
{

	//INIT GLUT/////////////////////
	////////////////////////////////
	//init window and OpenGL context
	glutInit(&argc, argv);
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize (1024, 768); 
	glutCreateWindow (argv[0]);
//	glutFullScreen();
	solid=true;


	//callback functions
	glutDisplayFunc(DrawScene);
	glutReshapeFunc(Reshape);
	glutKeyboardFunc(Keyboard);
	glutKeyboardUpFunc(KeyboardUp);
	glutPassiveMotionFunc(Mouse);
	//glutSetKeyRepeat(repeatMode);

	glEnable (GL_LIGHTING);	

	GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
	GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
	glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);	

	glEnable (GL_LIGHT0);	

	CFixedFrameRate *pFFR = new CFixedFrameRate(30);	

	while (1)
	{
		if(g_bKey_o)
		{	g_x-= MOVE_STEP*sin(g_yaw*PI/180);
			g_z-= MOVE_STEP*cos(g_yaw*PI/180);
		}
		if(g_bKey_d)	
		{	g_x+= MOVE_STEP*sin(g_yaw*PI/180);
			g_z+= MOVE_STEP*cos(g_yaw*PI/180);
		}
		if(g_bKey_s)	
		{
			g_yaw-= ANGLE_STEP; 
		}
		if(g_bKey_c)	
		{
			g_yaw+= ANGLE_STEP; 
		}

		//UPDATE////////////////////
		////////////////////////////
		//"move" the cube
		g_cubeAngle+= 0.1;
		//queued events?
		glutMainLoopEvent();


		//RENDER////////////////////
		////////////////////////////
		glutPostRedisplay();
		glutSwapBuffers();
		pFFR->endFrame();
	}
	delete pFFR;
   return 0;
}